﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RayTracer.Structures;
using RayTracer.Environment.Materials;
using System.Xml;


namespace RayTracer.Environment.Objects
{
    /// <summary>
    /// Modelliert ein Objekt vom Typ Kugel.
    /// </summary>
    [Serializable]
    public class Sphere : AObject
    {
        #region Attribute
        private float radius;
        #endregion Attribute

        #region Eigenschaften
        /// <summary>
        /// Gibt und setzt den Radius.
        /// </summary>
        public float Radius { get { return radius; } set { radius = value; } }
        #endregion Eigenschaften

        #region Methoden
        #region Konstruktoren und Destruktoren
        /// <summary>
        /// Instanziiert und initialisiert das Objekt mit Standardwerten.
        /// </summary>
        public Sphere() : this(new Structures.Point(), 1.0f) { }

        /// <summary>
        /// Instanziiert und initialisiert das Objekt mit Standardradius.
        /// </summary>
        /// <param name="position">Die Position der Kugel.</param>
        public Sphere(Structures.Point position) : this(position, 1.0f) { }

        /// <summary>
        /// Instanziiert und initialisiert das Objekt mit Standardposition.
        /// </summary>
        /// <param name="radius">Der Radius der Kugel.</param>
        public Sphere(float radius) : this(new Structures.Point(), radius) { }

        /// <summary>
        /// Instanziiert und initialisiert das Objekt.
        /// </summary>
        /// <param name="position">Die Position der Kugel.</param>
        /// <param name="radius">Der Radius der Kugel.</param>
        public Sphere(Structures.Point position, float radius)
        {
            this.radius = radius;
            this.Position = position;
        }
        #endregion Konstruktoren und Destruktoren

        #region Typenumwandlung
        /// <summary>
        /// Gibt eine Zeichenkettenrepräsentation der Klasse zurück.
        /// </summary>
        /// <returns>Die Zeichenkette.</returns>
        public override string ToString()
        {
            return "Kugel @ " + Position.ToString() + " Radius: " + radius.ToString();
        }

        /// <summary>
        /// Erstellt eine Kugel aus einem XML-Knoten.
        /// </summary>
        /// <param name="xmlNode">Das XML-Knoten.</param>
        /// <returns>Die Kugel.</returns>
        internal static Sphere FromXml(XmlNode xmlNode)
        {
            Sphere sphere = new Sphere();
            AObject.FromXml(xmlNode, sphere);
            XmlNode nodeRadius = xmlNode.SelectSingleNode("Radius");
            if (nodeRadius != null) float.TryParse(nodeRadius.InnerText, out sphere.radius);
            return sphere;
        }

        /// <summary>
        /// Wandelt die Kugel in einen XML-Knoten um.
        /// </summary>
        /// <param name="xmlDocument">Das zugrunde liegende XML-Dokument.</param>
        /// <returns>Der XML-Knoten.</returns>
        internal override XmlNode ToXml(XmlDocument xmlDocument)
        {
            XmlNode node = base.ToXml(xmlDocument);
            XmlNode nodeRadius = xmlDocument.CreateNode(XmlNodeType.Element, "Radius", null);
            nodeRadius.InnerText = this.radius.ToString();
            node.AppendChild(nodeRadius);
            return node;
        }
        #endregion Typenumwandlung
        #endregion Methoden
    }
}
